package main

//demo 并发访问问题
import (
	"fmt"
	"sync"
	"time"
)

//map  并发读写 产生错误
//fatal error: concurrent map read and map write
func MapConcurrentErr() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("MapConcurrentErr panic", err)
		}
	}()

	c := make(map[string]int)
	go func() { //开一个goroutine写map
		// 注意这里recover不到并发读写err
		defer func() {
			if err := recover(); err != nil {
				fmt.Println("MapConcurrentErr write panic", err)
			}
		}()
		for j := 0; j < 1000; j++ {
			c[fmt.Sprintf("%d", j)] = j
		}
	}()
	go func() { //开一个goroutine读map
		defer func() {
			// 注意这里recover不到err
			if err := recover(); err != nil {
				fmt.Println("MapConcurrentErr read panic", err)
			}
		}()

		for j := 0; j < 1000000; j++ {
			fmt.Println(c[fmt.Sprintf("%d", j)])
		}
	}()
	time.Sleep(time.Second * 20)

}

//sync map 并发读写安全
func SyncMapConcurrent() {
	c := sync.Map{}
	go func() { //开一个goroutine写map
		for j := 0; j < 1000000; j++ {
			c.Store(j, j)
			fmt.Println("store", j)
		}
	}()
	go func() { //开一个goroutine读map
		for j := 0; j < 1000000; j++ {
			load, ok := c.Load(j)
			fmt.Println("load", load, ok)
		}
	}()
	time.Sleep(time.Second * 20)

}
